<?php
/**
 * Base_App
 *
 * LICENSE
 *
 * This source file is subject to the new CC-GNU LGPL
 * It is available through the world-wide-web at this URL:
 * http://creativecommons.org/licenses/LGPL/2.1/
 *
 * @category   Base_App
 * @copyright  Copyright (c) 2009 Alexander fanatique* Thomas (me@alexander-thomas.net)
 * @license    http://creativecommons.org/licenses/LGPL/2.1/
 */
class Base_App_Acl extends Zend_Acl {
    private $cache = false;
    private static $_instance = null;

	/**
	 * Singleton getter
	 */
    public static function getInstance() {
		if (null === self::$_instance) {
			self::$_instance = new Base_App_Acl();
		}
		return self::$_instance;
    }
	/**Loads the ACL from cache
	 * @param string $cachedFile
	 * @return Zend_ACL object
	 */
    public function loadFromCache($cachedFile) {
		if (file_exists($cachedFile)) {// Check if the file already exists
			$file = file_get_contents($cachedFile);
			return unserialize($file);
		}else return null;
    }
	
	/**Rebuilds the ACL by parsing the config XML
	 * @param boolean $cache 
	 */
    public function rebuildResources($cache = false) {
		$appPath = Zend_Registry::get('applicationPath');
		$appConfig = Zend_Registry::get('applicationConfiguration');

		$configPath = $appPath . $appConfig->path->config;
		$file = $configPath . 'acl.xml';
		$aclConfig = new Zend_Config_Xml($file, null);
		/**Setup roles */
		foreach($aclConfig->roles->role AS $role) {
			if(empty($role->parent)) {
				$this->addRole(new Zend_Acl_Role($role->name));
			}else if($role->parent == '*') {	// Administrator inherits nothing, but is allowed all privileges
				$this->addRole(new Zend_Acl_Role($role->name));
				$this->allow($role->name);
			}else {
				$this->addRole(new Zend_Acl_Role($role->name), $role->parent);
			}

			/**Setup rules*/
			if(empty($role->rules->controller)) continue;
			else if(isset($role->rules->controller->name)){
				$controller = $role->rules->controller;
				// See if we already have it
				if (!$this->has($controller->name)) {
					$this->add(new Zend_Acl_Resource($controller->name));
				}
				
				$privileges = array();
				foreach($controller->action as $action) {
					$privileges[] = !is_object($action) ?  $action : $action->name;
				}
				$this->allow($role->name, $controller->name, $privileges);
			}else{
				foreach($role->rules->controller AS $controller) {
					// See if we already have it
					if (!$this->has($controller->name)) {
						$this->add(new Zend_Acl_Resource($controller->name));
					}

					$privileges = array();
					foreach($controller->action as $action) {
						$privileges[] = !is_object($action) ?  $action : $action->name;
					}
					$this->allow($role->name, $controller->name, $privileges);
				}				
			}
		}
			
		if($cache === true) {
			$serializedZendAcl = serialize($this);
			file_put_contents($cachedFile, $serializedZendAcl);
		}
	}

}
?>